#ifndef __POLYNOME_HPP__
#define __POLYNOME_HPP__

#include <gmpxx.h>
#include <iostream>

using namespace std;


class Polynome
{
   
   protected:
      
      int         _d;
      mpz_class   _m;
      mpz_class * _tabCoef;         // On a d+1 coefficients
      
   public:
      
      Polynome(char * inNb, int inNbDigits);
      
      Polynome(mpz_class * intabCoef, int degre) : _d(degre), _m(0)
      {
         _tabCoef = new mpz_class[_d + 1];
         
         if(intabCoef)
         {
            for(int i = 0 ; i < _d + 1 ; i++)
            {
               _tabCoef[i] = intabCoef[i];
            }
         }
      }
      
      Polynome(Polynome & inPolynome)
      {
         _d = inPolynome._d;
         _m = inPolynome._m;
         _tabCoef = new mpz_class[_d + 1];
         
         for(int i = 0 ; i < _d + 1 ; i++)
         {
            _tabCoef[i] = inPolynome._tabCoef[i];
         }
      }
      
      ~Polynome();
      
      int getD()                 const { return _d; }
      mpz_class getM()           const { return _m; }
      mpz_class * getPoly()      const { return _tabCoef; }
      mpz_class getCoef(int inI) const { return _tabCoef[inI]; }
      
      void setCoef(int inI, mpz_class & inCoef) { _tabCoef[inI] = inCoef; }
      
      void degre(int inNbDigits);
      
      void base(mpz_class inN);
      
      
      void insert(int i, const mpz_class & inCoef)
      {
         _tabCoef[i] = inCoef;
      }
      
      void coef(mpz_class inN);
      
      void recherchePoly(mpz_class inN);
      
      bool verifPoly(mpz_class inN) const
      {
         mpz_class nombre = eval(_m);
         return (nombre == inN)? true : false;
      }
      
      mpz_class bpowdf(mpz_class & a, mpz_class & b);
      
      mpz_class eval(mpz_class inVal) const;
      
      mpz_class evalFPrime(mpz_class & inVal);
      
      Polynome * FPrimeCarreModF();
      
      Polynome * powPModF(int p);
      
      void generateFile() const;
      
      friend ostream & operator << (ostream & o, const Polynome & inPoly);


};



#endif
